home *** CD-ROM | disk | FTP | other *** search
- Copyright (c) 1991-1993 Borland International, Inc.
- All Rights Reserved.
-
- THE BLADERUNNER UI LANGUAGE EXTENSIONS
- --------------------------------------
- Bladerunner extends the dBASE language with new commands and
- functions for creating graphical, event-driven user interfaces.
- For compatibility with DOS applications, Bladerunner still
- supports the dBASE IV windowing and menu mechanisms. However, to
- take full advantage of the Windows environment, you need to
- understand and use the new extensions. This document introduces
- the new UI extensions and describes the steps for creating and
- using windows.
-
- Contents
- --------
-
- I. Overview
- II. Summary of Steps
- III. Step 1 - Define the window
- IV. Step 2 - Define controls
- V. Step 3 - Assign actions
- VI. Step 4 - Read the window
- VII. Upgrading dBASE DOS screen forms
-
-
- Overview
- --------
-
- In a Bladerunner application, the window is the primary user
- interface container. Windows can contain controls, such as entry
- fields and list boxes, for interacting with the user and can also
- contain other windows. When you design the user interface for
- your application, you are essentially designing its windows.
-
- The Bladerunner mechanism for working with windows is familiar to
- dBASE IV programmers, with these important differences:
-
- - In dBASE IV, there is an active state for GETs (READ) and an
- active state for menus (ACTIVATE MENU/POPUP); both can be
- visible, but only one at a time is active. In Bladerunner,
- there is a single active state for a window. Use READMODAL()
- or OPEN WINDOW to activate GETs (called entry fields), menus,
- and any other controls in the window.
-
- - In dBASE IV, only one window at a time can be active. In
- Bladerunner, several windows can be active at once. A new
- command, OPEN WINDOW, displays a window and continues program
- execution, letting you display more windows, or execute other
- code, without stopping execution to get user responses.
-
- - In dBASE IV, you DEFINE a window, ACTIVATE it, display your
- SAYs and GETs, then READ. In Bladerunner, you don't ACTIVATE
- windows; instead, you DEFINE the window, DEFINE controls OF
- the window, then READMODAL() or OPEN WINDOW. The next section
- describes these steps in more detail.
-
- Summary of Steps
- ----------------
-
- Below is a summary of the steps for creating and reading a
- Bladerunner window. A detailed explanation of each step follows
- the summary.
-
- 1. Define the window with
-
- DEFINE WINDOW
-
- 2. Define controls for the window with
-
- DEFINE <control name> OF <window name>
-
- 3. Assign actions with
-
- ON SELECTION WINDOW
- ON SELECTION PULLDOWN
-
- 4. Read the window with
-
- READMODAL() or
- OPEN WINDOW
-
- Step 1 - Define the Window
- --------------------------
-
- DEFINE WINDOW has several options for specifying the look and
- behavior of the window. Using these options in different
- combinations, you can define input windows, dialog boxes or any
- other kind of window. Type HELP DEFINE WINDOW from the Command
- Window for a list of options.
-
- The Default Font and the Coordinate Plane
-
- Each window has a default font which Bladerunner uses to display
- any controls or output that don't specify a font. Use the FONT
- option of DEFINE WINDOW to set the window's default font. If you
- don't use the FONT option, the default font is the Windows system
- font.
-
- A window's default font is especially important because it
- defines the size of the coordinate plane for placing controls in
- the window. That is, the row height is determined by the line
- height of the default font, and the column width is determined by
- the character width of the default font. So, when you issue this
- command:
-
- DEFINE TEXT FNHeading OF MyWindow AT 6,16 PROMPT "First Name"
-
- Bladerunner displays "First Name" at row 6 (six lines down in the
- default font), column 16 (sixteen characters across in the
- default font).
-
- Proportional fonts, such as Helvetica or Times, have varied
- widths for each character: an "i" takes up less space than a "w."
- If you specify a proportional font as the default font,
- Bladerunner uses the average character width as the column width.
- For this reason, using a non-proportional font as the default
- window font makes working with window coordinates a little
- easier. With a non-proportional default font, you can still
- specify proportional fonts for the controls that contain text.
- "Specifying Coordinates" in Step 2 describes two new functions,
- NEXTROW() and NEXTCOL(), for displaying controls with varied
- fonts.
-
- Dialog Boxes
-
- A dialog box is a window you create for getting information from
- the user. The DLGFRAME option of DEFINE WINDOW makes the window's
- border look like a standard Windows dialog box, and makes the
- window non-sizeable. These other options of DEFINE WINDOW are
- useful for creating dialog boxes:
-
- NOMAXIMIZE Displays the window without a Maximize button.
- NOMINIMIZE Displays the window without a Minimize button.
- AUTOSIZE Automatically sets the lower right coordinate of
- the window to contain the lowest and rightmost
- control in the window.
-
- This example defines a dialog box for prompting the user to enter
- a customer name:
-
- DEFINE WINDOW MyDialog AT 10,10 OF DESKTOP DLGFRAME NOMAXIMIZE;
- NOMINIMIZE AUTOSIZE MESSAGE "Enter a customer name"
- cName = SPACE(30)
- DEFINE TEXT Head1 AT 2,2 OF MyDialog PROMPT "Customer name:"
- DEFINE ENTRYFIELD GetName WITH cName at 2,NEXTCOL() OF MyDialog
- DEFINE PUSHBUTTON Ok AT 4,5 OF MyDialog PROMPT "OK"
- DEFINE PUSHBUTTON Cancel AT 4,NEXTCOL() OF MyDialog ;
- PROMPT "Cancel"
-
- Step 2 - Define controls
- ------------------------
-
- A control is an object you place in a window for interacting with
- the user. Bladerunner provides several controls for displaying
- and editing data, such as list boxes and radio buttons, and
- controls for getting user responses, such as pull-down menus and
- pushbuttons. You place a control in a window by defining the
- control. Here is the basic syntax:
-
- DEFINE <control name> OF <window name> AT <coordinates>
-
- The following examples define controls for MyWindow:
-
- DEFINE TEXT Get1Title OF MyWindow AT 1,5 PROMPT "Enter a name"
- DEFINE ENTRYFIELD Get1 WITH mName OF MyWindow AT 1,20
- DEFINE PUSHBUTTON Push1 OF MyWindow AT 3,2 PROMPT "OK"
- DEFINE LISTBOX List1 OF MyWindow FROM 3,10 TO 9,25 PROMPT FILES
-
- Specifying coordinates
-
- For precise placement of controls, you can specify coordinates
- with decimal values. For example:
-
- DEFINE PUSHBUTTON OK AT 3.5, 1.5 OF MyWindow PROMPT "OK"
-
- Controls that contain text, such as entry fields and
- radiobuttons, have a FONT option. Even though each control you
- place may specify a different font, the coordinates for placing
- controls are always based on the window's default font. When
- positioning controls with different fonts, the relative
- addressing technique commonly used in dBASE DOS, using ROW() and
- COL(), can misalign controls. For instance:
-
- @ 1,2 SAY "First line"
- @ ROW()+1,2 SAY "Second line"
- @ ROW()+1,2 SAY "Third line"
-
- will display correctly aligned only if all three objects and the
- window in which they are displayed use the same font.
-
- To accomodate relative addressing with varied fonts, Bladerunner
- provides NEXTROW() and NEXTCOL(). NEXTROW() returns the next
- available row on the coordinate plane given the last control
- drawn; NEXTCOL() returns the next available column. For instance
-
- DEFINE FONT Times10 ........
- @ 2,2 SAY "First line" FONT Times10
- @ NEXTROW(),2 SAY "Second line" FONT Arial24
- @ NEXTROW(),2 SAY "Third line" FONT Script48
- @ ROW(),NEXTCOL() SAY "Second SAY on Third line" FONT Times10
-
- will display correctly aligned regardless of the fonts you
- specify.
-
-
- Data Controls
-
- These controls display and edit data. ENTRYFIELDs correspond to
- GETs, and TEXT controls correspond to SAYs.
-
- DEFINE... So a user can
- --------- -------------
- ENTRYFIELD Enter a single value
- COMBOBOX Enter or select one of any number of values
- SPINBOX Enter or select one in an ordered set of values
- SCROLLBAR Select one in an ordered set of values
- CHECKBOX Select one of two logical values
- RADIOBUTTONS Select one of a few values
- LISTBOX Select one or more of any number of values
- BROWSE View or edit fields in a table - tabular view
- EDIT View or edit fields in a table - record view
- EDITOR View or edit text
- BOX See a box
- TEXT See text as a heading, desc., or instruction.
- GRAPH See and interact with a graph of table data
- IMAGE See a bitmapped image
-
-
- Action controls
-
- These controls, menus, speedbars, and pushbuttons, cause actions
- to occur.
-
- Bladerunner supports dBASE IV's horizontal bar menus (created
- with DEFINE MENU and DEFINE PAD) and popup menus (created with
- DEFINE POPUP and DEFINE BAR) only for dBASE IV compatibility. To
- create menus in Bladerunner, use these new commands:
-
- DEFINE MENU CHOICE Defines an item on the menu bar
- DEFINE PULLDOWN Defines a pulldown menu
- DEFINE PULLDOWN CHOICE Defines an item on a pulldown menu
- ON MENU CHOICE Assigns a pulldown menu to a menu
- bar item
-
- A Bladerunner window can have just one menu bar. Consequently,
- you don't explicitly define menu bars; you just define each menu
- item OF the window with DEFINE MENU CHOICE. The menu items
- display in the order you define them on a bar attached to the top
- border.
-
- Use DEFINE PULLDOWN to define a pull-down menu and DEFINE
- PULLDOWN CHOICE to define each item on the pull-down menu. Use ON
- MENU CHOICE to attach a pulldown menu to a menu bar item.
-
- Menu bars and pulldown menus become active, along with any other
- controls in the window, when you read the window.
-
- DEFINE MENU CHOICE mFile OF MyWin PROMPT "File"
- DEFINE MENU CHOICE mEdit OF MyWin PROMPT "Edit"
- ....
- DEFINE PULLDOWN pFile
- DEFINE PULLDOWN CHOICE pFile1 OF pFile PROMPT "Delete"
- DEFINE PULLDOWN CHOICE pFile2 OF pFile PROMPT "Recall"
- ....
- ON MENU CHOICE mFile OF MyWin ACTIVATE PULLDOWN pFile
- ....
-
- A speedbar is a row or column of related buttons that cause an
- action when pressed. In Windows applications, speedbars typically
- duplicate menu items, offering a quick way to cause an action
- without having to find it on a menu. For instance, Print can be
- an item on the File menu and also a button on the speedbar.
-
- Use DEFINE SPEEDBAR to create a speedbar definition and DEFINE
- SPEEDBUTTON to define each button on the speedbar. DEFINE
- SPEEDBUTTON has an EXECUTE option for specifying a command or
- subroutine to run when the button is pressed.
-
- Note: In this Alpha release, speedbars are not yet implemented.
-
- A pushbutton is a single button that causes an action when
- pressed. For instance, an OK pushbutton can save and exit from a
- window, and a Cancel pushbutton can exit without saving.
- Typically, pushbuttons confirm an entry or selection made in
- other controls. Use DEFINE PUSHBUTTON to define pushbuttons.
-
- In Windows applications, if a window has a menu, the menu
- typically offers an item for exiting the window. If a window has
- no menu, push buttons (such as Cancel or Ok) typically exit the
- window. A window should not contain both push buttons and menu
- items for exiting.
-
-
- Step 3 - Assign actions
- -----------------------
-
- You can assign actions to pull-down menu items, push buttons, and
- to the window itself. Assigning actions to menus is similar to
- dBASE IV. To assign actions to push buttons and windows, you need
- to understand a new concept of window selection.
-
- Pulldown Menus
-
- Assign actions to pull-down menus with ON SELECTION PULLDOWN.
- Typically, ON SELECTION PULLDOWN calls a procedure that uses
- CHOICE() or PROMPT() to determine which item was selected, then
- branches to other commands based on the selection.
-
- Window Selection
-
- Selecting a window accepts changes made to the window's controls,
- much like Ctrl-W accepts values in dBASE DOS.
-
- A user selects a window by:
- - Clicking on a pushbutton
- - Pressing Enter when the cursor is in the window (See Enter key
- behavior in Step 4 for details.)
- - Pressing Ctrl-Enter
-
- A user exits a window without selecting it by:
- - Pressing Esc. You can prevent this with the NoEscape option of
- OPEN WINDOW, or passing a logical escape parameter to
- READMODAL().
- - Double-clicking in the window's control box, or selecting
- Close from the control menu, if the window has a control box.
- - Pressing Ctrl-F4.
-
- Use ON SELECTION WINDOW to specify a procedure to execute when a
- window is selected.
-
- Typically, if a window contains one or more push buttons, the ON
- SELECTION WINDOW procedure uses ACTIVECONTROL() to determine
- which push button was pressed, then branches to other commands.
- Push buttons differ from other controls in that one push button
- is always chosen when the user selects the window. The chosen
- push button is either the one the user presses, or the default
- push button if none is pressed.
-
-
- Trapping keystrokes
-
- You can assign actions to keystrokes, using the familiar dBASE
- DOS command, ON KEY. However, certain keystroke combinations are
- common to all Windows applications. For instance, Alt-F4 closes
- the active window or dialog box. Your application should not map
- other behavior to these reserved key combinations.
-
-
- Step 4 - Read the window
- ------------------------
-
- Bladerunner provides two methods for reading windows: READMODAL()
- and OPEN WINDOW.
-
- READMODAL()
-
- Use READMODAL( <window name> ) to stop program execution and read
- a window. READMODAL() performs a "modal" read of a window. That
- is, it activates the window with exclusive focus -- the user
- cannot change focus to another window without first exiting the
- READMODAL() window.
-
- You can use READMODAL() in a command line the same way you would
- use other fuctions, like GETFILE(), that display a dialog box and
- return a value. By default, READMODAL() returns the name of the
- control that has focus when the user selects the window. (See
- "Window Selection" in Step 3.) You can query the READMODAL()
- return value to determine the user's action.
-
- DEFINE WINDOW Alert FROM 5,5 to 20,65 OF DESKTOP
- DEFINE PUSHBUTTON Ok OF Alert at 2,2 PROMPT "OK"
- DEFINE PUSHBUTTON Cancel OF Alert at 2,14 PROMPT "Cancel"
- ReturnVal = ReadModal("Alert")
-
- IF ReturnVal = "OK"
- DO OKProc
- ELSE
- DO CancelProc
- ENDIF
-
- You can specify your own return value for READMODAL() using the
- WITH option of CLOSE WINDOW. This makes it easy to re-use your
- window and dialog box definitions. The following example displays
- the Alert window and returns "My return value."
-
- DEFINE WINDOW Alert FROM 5,5 to 20,65 OF DESKTOP
- DEFINE PUSHBUTTON Ok OF Alert at 2,2 PROMPT "OK"
- DEFINE PUSHBUTTON Cancel OF Alert at 2,14 PROMPT "Cancel"
- ON SELECTION WINDOW Alert CLOSE WINDOW WITH "My return value"
- ReturnVal = ReadModal("Alert")
-
- You can nest READMODAL() statements. For instance, a window
- displayed with READMODAL() can contain a push button that
- launches another READMODAL() window. In this case, the user must
- exit the second window, then the first window, before switching
- focus to another window.
-
- OPEN WINDOW
-
- OPEN WINDOW performs a "non-modal" read of a window; the user can
- switch focus to another window without exiting the current
- window. Choose OPEN WINDOW over READMODAL() when you want to have
- more than one window active simultaneously.
-
- Also, unlike READMODAL(), OPEN WINDOW does not stop program
- execution. This allows you to execute more OPEN WINDOW commands,
- or any other code, after reading a window.
-
- While OPEN WINDOW represents a break from traditional dBASE
- coding techniques, where READ commands temporarily halt
- execution, it allows you to design true event-driven
- applications. A typical event-driven application simply sets up
- the environment, and creates and displays its windows. Further
- execution is determined by the user.
-
- Having execution continue after OPEN WINDOW, raises certain
- issues your program needs to handle. Here are the issues with our
- current recommendations (better solutions should follow this
- Alpha release -- your suggestions are encouraged!):
-
- - As always occurs in dBASE, non-PUBLIC memory variables are
- released when the program they are declared in finishes
- executing. So, if a program creates a window, assigns some
- memory variables, reads the window with OPEN WINDOW, then ends,
- the variables are released even though the window is now
- active. To avoid releasing these variables, you can declare
- them PUBLIC.
-
- - If you define controls that are based on fields in a table (for
- example, a GET or ENTRYFIELD using a field name), then read the
- window with OPEN WINDOW, then close the table, the controls will
- not work because the table is no longer in use. Make sure you
- don't close the table until the window is closed.
-
- - As always occurs in dBASE, functions and procedures declared in
- a program are unavailable when the program finishes executing.
- So, if a program contains function declarations, assigns these
- functions to event handlers such as a VALID or OnClosed option,
- then reads the window with OPEN WINDOW, the functions are not
- available when the program ends, even though the window may
- still be active. To make sure all subroutines attached to event
- handlers remain available, declare them in a common procedure
- file that always stays open.
-
-
- The following example shows how you can use OPEN WINDOW to read
- two windows. The user can launch Calc.prg to activate the
- Calculator, then launch Invoice.prg to activate the Invoice
- window. Both windows are then available, and the user can switch
- focus between them.
-
- * Calc.prg - a calculator
- DEFINE WINDOW Calculator FROM 10,2
- * DEFINE controls OF Calulator
- ....
- OPEN WINDOW Calculator && Reads Calculator
- * More code here, if necessary
- ....
- RETURN
-
- * Invoice.prg - entry window for an invoice
- DEFINE WINDOW Invoice FROM 1,1
- * DEFINE controls OF Invoice
- ....
- OPEN WINDOW Invoice && Reads Invoice
- * More code here, if necessary
- ....
- RETURN
-
-
- Enter key behavior
-
- One of the differences between dBASE DOS and Windows applications
- is the behavior of the Enter key. In dBASE DOS, pressing the
- Enter key moves the cursor to the next GET; pressing Enter on the
- last GET terminates the READ. In Windows applications, the Tab
- key typically moves to the next control. Pressing Enter accepts
- the controls much like Ctrl-W does in dBASE DOS.
-
- In Bladerunner, pressing Enter when the cursor is in the window
- body, but not in an editor object, accepts and exits the window.
- Tab and Shift-Tab move the cursor to the next and previous
- controls respectively.
-
- While the Windows Enter key behavior is preferable in a Windows
- application, you might want to retain the DOS behavior to
- maintain consistency with your DOS applications. Bladerunner
- provides SET CUAENTER to specify the behavior of the Enter key.
- SET CUAENTER OFF causes the Enter key to behave as in dBASE DOS;
- SET CUAENTER ON follows the Windows behavior.
-
- Ctrl-Enter accepts and exits and window regardless of the SET
- CUAENTER setting.
-
- Upgrading dBASE DOS screen forms
- --------------------------------
-
- The Bladerunner UI language extensions replace the familiar dBASE
- DOS @...SAY/GET commands with the new DEFINE commands, DEFINE
- TEXT and DEFINE ENTRYFIELD. But that doesn't mean you have to
- stop using @...SAY/GET. To help you upgrade your dBASE DOS screen
- forms, Bladerunner provides two new commands, SET WINDOW TO
- <window name> and SET WINDOW ON. These commands direct
- @...SAY/GET output to <window name>. You can then define new
- controls for <window name> without re-writing your @...SAY/GETs.
-
- Follow these steps:
-
- 1.If your screen form is displayed in a window, consider adding
- some of the Bladerunner options to your DEFINE WINDOW command,
- such as DLGFRAME or AUTOSIZE. Otherwise, define a new window.
-
- 2.Replace the ACTIVATE WINDOW command with SET WINDOW TO
- <window name> and SET WINDOW ON.
-
- 3.Define any new controls you want to add to your form.
-
- 4.If you activate your form with SET FORMAT TO, remove that
- line. Instead, run the format file like a program, as DO
- <format file name>.
-
- 5.Replace the READ command with READMODAL().
-
- Here is a sample dBASE DOS screen form (Assume an open table
- contains the fields, FName, LName, and Color):
-
-
- DEFINE WINDOW SelColor FROM 1,1 to 12,50
- ACTIVATE WINDOW SelColor
- @ 2,10 SAY "First Name" GET FName
- @ 4,10 SAY "Last Name" GET LName
- @ 6,10 SAY "Color choice" GET Color
- READ
-
- Here is the same screen form upgraded to Bladerunner:
-
- DEFINE WINDOW SelColor FROM 1,1 AUTOSIZE
- SET WINDOW TO SelColor
- SET WINDOW ON
- @ 2,10 SAY "First Name" GET FName
- @ 4,10 SAY "Last Name GET LName
- DEFINE RADIOBUTTON RadioClr WITH Color OF SelColor AT 6,23;
- PROMPT "Red" PICK "R", "Green" PICK "G", "Blue" PICK "B";
- HORIZONTAL
- READMODAL("SelColor")
-
-
- ------------------------> EOF: UI_exten.TXT <--------------------
-